#ifndef __CRASHGUARD
#define __CRASHGUARD

// INCLUDES -------------------------------------------------------------------------
#include "stdlib.h"	// abort()
#include "stdio.h"	// printf()

// DEFINES --------------------------------------------------------------------------

// assert check for entire conditions
#ifndef NDEBUG
	/* callable assert function with msg and parameters:
	 - prints line/file-location
	 - prints error message + optional variables
	 - hard aborts program
	*/
	#define ASSERT_GUARD(condition, msg, ...)			\
	{													\
		if (!(condition))								\
		{ 												\
			printf(                                     \
				"%s:%i: assertation: " msg ".\n",		\
				__FILE__,                               \
				__LINE__,                               \
				##__VA_ARGS__                           \
			); 											\
			abort(); 									\
		}; 												\
	};
#else
	// no performance should be eaten here...
	#define ASSERT_GUARD(condition, msg, ...) ;
#endif

// assert check for NULL pointer
#define NULL_GUARD(p) 					{ ASSERT_GUARD(p != NULL, "NULL pointer as target"); }

// assert check for floating-point zero value
#define ZERO_GUARD(k) 					{ ASSERT_GUARD(k != 0.0f, "division by zero"); }

// assert check for out-of-bounds address locations
#define BOUNDS_GUARD(dst, base, elements)	{ printf("BOUNDS GUARD [dst: 0x%x, base: 0x%x, top: 0x%x]\n", \
		                                             dst, base, base+(elements-1)); \
											  ASSERT_GUARD(dst <= base+(elements-1), "access to address out-of-bound"); }

// standard printf macro for warnings, etc
#define MSG(msg, ...)   				{ printf(msg, ##__VA_ARGS__); }

#endif // __CRASHGUARD
